/**
 * Class used to dynamically add new action methods with callbacks
 * Uses method chaining.
 * Use method define(name) to define action, withCallback(callback) to add callback and addParam(name) to add parameters
 * Sample Usage (function create must be used as last one)
 * connector.actions.movePlayer = connector.actions.define("movePlayer").withCallback(callback).addParam("direction").addParam("position").create();
 * then use action like
 * connector.actions.movePlayer("LEFT", {x: 10, y: 10});
 *
 */
var BristleActions = function() {
  this.parameters = {};
};

/**
 * Set connector for event handling
 * Call this method in initialization part of starting framework
 * @param connector
 */
BristleActions.prototype.setConnector = function(connector) {
  this.connectorInstance = connector;
  this.callbacks = connector.fRequestCallbacks;
};

/**
 * Starts creation process of adding new dynamic method
 * @param name name of the server method to call
 */
BristleActions.prototype.define = function(name) {
  this.actionName = name;
  return this;
};

/**
 * Sets callback object or callback function for invoking method
 * Usages
 * .withCallback(onSuccess, onFailure)
 * .withCallback(onSuccess)
 * .withCallback(callbackObject)
 *
 * sample callback object
 *    var callback = {
 *       onSuccess: function(response) {
 *       },
 *       onFailure: function(exception) {
 *       }
 *     };
 * If you provide only one function, it will be used as onSuccess function, onFailure will be set to default framework failure function
 * @param callback
 */
BristleActions.prototype.withCallback = function(callback) {
  if (arguments.length == 2) {
    var callbackObject = {};
    callbackObject.onSuccess = arguments[0];
    callbackObject.onFailure = arguments[1];
    this.callback = callbackObject;
  } else {
    this.callback = callback;
  }
  return this;
};

/**
 * Adds new param to method call. Value should be name of param send with method call
 * Order of added params should be same as method call arguments
 * @param param name of the param to add
 */
BristleActions.prototype.addParam = function(param) {
  this.parameters[param] = param;
  return this;
};

/**
 * Adds new params to method call. Value should be list of names of params send with method call
 * Order of added params should be same as method call arguments
 * @param params names of the params to add
 */
BristleActions.prototype.addParams = function() {
  for (var i = 0; i < arguments.length; i++) {
    this.parameters[arguments[i]] = arguments[i];
  }
  return this;
};

/**
 * Creates new methods with callback and params added in method creation chain
 * Use method define(name) to define action, withCallback(callback) to add callback and addParam(name) to add parameters
 * @returns action function that should be added to connector.actions
 */
BristleActions.prototype.create = function() {
  var creationArguments = this.parameters;
  var action = this.actionName;
  var callbackFunction = this.callback;
  var remoteAction = function() {
    var params = {};
    var argCounter = 0;
    for (var arg in creationArguments) {
      params[arg] = arguments[argCounter];
      argCounter++;
    }
    this.connectorInstance.requestAction(action, params, callbackFunction);
  };
  this.parameters = [];
  this.callback = undefined;
  this.actionName = '';
  return remoteAction;
};


